﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;

namespace ChineseChess.Game.AI
{
    public class Ai7:BaseAi
    {
        /// <summary>
        /// Ai的算法
        /// </summary>
        /// <param name="pieceList">当前局面</param>
        /// <param name="canvas"></param>
        /// <param name="deep">计算深度</param>
        public static void Run(List<Piece> pieceList, Canvas canvas, int deep = 4)
        {
            List<Piece> pies = pieceList;
            initTable();
            Moves mv = findBestNextStep(deep, pies, false);

            Piece p = clearPiece(pieceList, (int)mv.p.X, (int)mv.p.Y);//吃掉子
            //MessageBox.Show(mv.pie.Name.ToString() + mv.pie.X + "," + mv.pie.Y + ", " + mv.p.ToString());
            if (p != null)
            {
                canvas.Children.Remove(p);
            }

            for (int i = 0; i < pieceList.Count; i++)
            {
                var pie = pieceList[i];
                if (pie.X == mv.pie.X && pie.Y == mv.pie.Y)
                {
                    pie.X = (int)mv.p.X;
                    pie.Y = (int)mv.p.Y;
                    pie.InvalidateVisual();
                }
            }
        }

        private static int MIN_SCORE = -9999;
        private static int MAX_SCORE = 9999;

        private static Moves findBestNextStep(int depth, List<Piece> pies, bool isred)
        {
            Moves result = Search(depth, pies, isred, MAX_SCORE + 1);
            return result;
        }

        private static Moves Search(int depth, List<Piece> pies, bool isred,int now_best)
        {
            var steps = generateMoves(pies, isred);
            Moves result = null;
            int score = 0;
            int best_id = 0;
            int best_score = MIN_SCORE;
            if (isred)
            {
                best_score = MAX_SCORE;
            }

            for (int id = 0; id < steps.Count; id++)
            {
                Moves mv = steps[id];
                Moves historyMv = null;
                Piece eatedPie = MovePie(pies, mv, out historyMv);

                if(depth == 1)
                {
                    score = evaluate(pies, isred);
                }
                else
                {
                    score = evaluate(pies, isred);
                    if (Math.Abs(score) < 9000)
                    {
                        result = Search(depth - 1, pies, !isred, best_score);
                        score = result.score;
                    }
                }

                BackMovePie(pies,eatedPie,historyMv);

                if((!isred && score >= best_score) || (isred && score <= best_score))
                {

                    //更新最优走法
                    if (! (Math.Abs(score - best_score) == 0) )
                    {
                        best_id = id;
                        best_score = score;
                    }
                }

                // a-b 剪子
                if (isred && now_best >best_score)
                {
                    result =  steps[best_id];
                    result.score = best_score; 
                    return result;
                }
                else if(!isred && now_best < best_score)
                {
                    result = steps[best_id];
                    result.score = best_score;
                    return result;
                } 
            }
            result = steps[best_id];
            result.score = best_score;
            return result;
        }
    }
}
